package com.kexio.file.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kexio.file.entity.FileVersion;
import com.kexio.file.mapper.FileVersionMapper;
import com.kexio.file.service.FileVersionService;
import com.kexio.file.service.StorageObjectService;
import com.kexio.file.vo.FileVersionVO;

import cn.hutool.core.util.StrUtil;

/**
 * 文件版本管理服务实现
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
@Service
public class FileVersionServiceImpl extends ServiceImpl<FileVersionMapper, FileVersion> implements FileVersionService {

    private static final Logger log = LoggerFactory.getLogger(FileVersionServiceImpl.class);

    @Autowired
    private StorageObjectService storageObjectService;

    @Override
    @Transactional
    public FileVersion createNewVersion(String fileId, String storageObjectId, String changeLog, 
                                        String versionTags, Boolean setAsCurrent) {
        if (!StringUtils.hasText(fileId) || !StringUtils.hasText(storageObjectId)) {
            throw new IllegalArgumentException("文件ID和存储对象ID不能为空");
        }

        try {
            // 1. 获取当前最大版本号
            Integer maxVersionNumber = baseMapper.selectMaxVersionNumberByFileId(fileId);
            int newVersionNumber = (maxVersionNumber != null ? maxVersionNumber : 0) + 1;

            // 2. 创建新版本记录
            FileVersion newVersion = new FileVersion();
            newVersion.setFileId(fileId);
            newVersion.setStorageObjectId(storageObjectId);
            newVersion.setVersionNumber(newVersionNumber);
            newVersion.setVersionName("v" + newVersionNumber);
            newVersion.setVersionDisplayName("版本 " + newVersionNumber);
            newVersion.setIsCurrent(setAsCurrent != null ? setAsCurrent : true);
            newVersion.setChangeLog(changeLog);
            newVersion.setVersionTags(versionTags);
            newVersion.setStatus(1); // 正常状态
            // 注意：不需要手动设置createTime和createBy，BaseFieldsMetaObjectHandler会自动填充
            // newVersion.setCreateTime(LocalDateTime.now());
            // newVersion.setCreateBy(getCurrentUserId());

            // 3. 保存新版本 - 系统会自动填充审计字段
            save(newVersion);

            // 4. 如果设置为当前版本，需要更新其他版本的状态
            if (newVersion.getIsCurrent()) {
                baseMapper.updateCurrentVersion(fileId, newVersion.getId());
            }

            // 5. 增加存储对象引用计数
            storageObjectService.incrementReferenceCount(storageObjectId, 1);

            log.info("创建文件版本成功: fileId={}, versionId={}, versionNumber={}, storageObjectId={}", 
                    fileId, newVersion.getId(), newVersionNumber, storageObjectId);

            return newVersion;

        } catch (Exception e) {
            log.error("创建文件版本失败: fileId={}, storageObjectId={}", fileId, storageObjectId, e);
            throw new RuntimeException("创建文件版本失败: " + e.getMessage());
        }
    }

    @Override
    public List<FileVersionVO> getVersionsByFileId(String fileId) {
        if (!StringUtils.hasText(fileId)) {
            throw new IllegalArgumentException("文件ID不能为空");
        }

        List<FileVersion> versions = baseMapper.selectVersionsByFileId(fileId);
        return convertToVOList(versions);
    }

    @Override
    public FileVersionVO getCurrentVersion(String fileId) {
        if (!StringUtils.hasText(fileId)) {
            throw new IllegalArgumentException("文件ID不能为空");
        }

        FileVersion currentVersion = baseMapper.selectCurrentVersionByFileId(fileId);
        return currentVersion != null ? convertToVO(currentVersion) : null;
    }

    @Override
    public FileVersionVO getVersionByNumber(String fileId, Integer versionNumber) {
        if (!StringUtils.hasText(fileId) || versionNumber == null || versionNumber <= 0) {
            throw new IllegalArgumentException("文件ID和版本号不能为空且版本号必须大于0");
        }

        FileVersion version = baseMapper.selectVersionByFileIdAndNumber(fileId, versionNumber);
        return version != null ? convertToVO(version) : null;
    }

    @Override
    @Transactional
    public boolean switchToVersion(String fileId, String versionId) {
        if (!StringUtils.hasText(fileId) || !StringUtils.hasText(versionId)) {
            throw new IllegalArgumentException("文件ID和版本ID不能为空");
        }

        try {
            // 验证版本是否存在
            FileVersion targetVersion = getById(versionId);
            if (targetVersion == null || !fileId.equals(targetVersion.getFileId())) {
                throw new IllegalArgumentException("版本不存在或不属于指定文件");
            }

            // 更新当前版本
            int affectedRows = baseMapper.updateCurrentVersion(fileId, versionId);
            
            log.info("切换文件版本成功: fileId={}, versionId={}, affectedRows={}", fileId, versionId, affectedRows);
            return affectedRows > 0;

        } catch (Exception e) {
            log.error("切换文件版本失败: fileId={}, versionId={}", fileId, versionId, e);
            return false;
        }
    }

    @Override
    @Transactional
    public FileVersion rollbackToVersion(String fileId, Integer versionNumber, String changeLog) {
        if (!StringUtils.hasText(fileId) || versionNumber == null || versionNumber <= 0) {
            throw new IllegalArgumentException("文件ID和版本号不能为空且版本号必须大于0");
        }

        try {
            // 1. 获取目标版本
            FileVersion targetVersion = baseMapper.selectVersionByFileIdAndNumber(fileId, versionNumber);
            if (targetVersion == null) {
                throw new IllegalArgumentException("目标版本不存在: " + versionNumber);
            }

            // 2. 创建回滚版本（复用存储对象）
            String rollbackChangeLog = StrUtil.isNotBlank(changeLog) ? changeLog : 
                    "回滚到版本 " + versionNumber + " (" + targetVersion.getVersionName() + ")";
            
            return createNewVersion(fileId, targetVersion.getStorageObjectId(), 
                                  rollbackChangeLog, "rollback", true);

        } catch (Exception e) {
            log.error("回滚文件版本失败: fileId={}, versionNumber={}", fileId, versionNumber, e);
            throw new RuntimeException("回滚文件版本失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public boolean deleteVersion(String versionId, Boolean force) {
        if (!StringUtils.hasText(versionId)) {
            throw new IllegalArgumentException("版本ID不能为空");
        }

        try {
            FileVersion version = getById(versionId);
            if (version == null) {
                return true; // 版本不存在，视为删除成功
            }

            // 检查是否为当前版本
            if (version.getIsCurrent() && (force == null || !force)) {
                throw new IllegalStateException("不能删除当前版本，请先切换到其他版本或使用强制删除");
            }

            // 软删除版本
            removeById(versionId);

            // 减少存储对象引用计数
            storageObjectService.decrementReferenceCount(version.getStorageObjectId(), 1);

            log.info("删除文件版本成功: versionId={}, fileId={}, storageObjectId={}", 
                    versionId, version.getFileId(), version.getStorageObjectId());
            return true;

        } catch (Exception e) {
            log.error("删除文件版本失败: versionId={}", versionId, e);
            return false;
        }
    }

    @Override
    @Transactional
    public boolean deleteAllVersions(String fileId) {
        if (!StringUtils.hasText(fileId)) {
            throw new IllegalArgumentException("文件ID不能为空");
        }

        try {
            // 获取所有版本
            List<FileVersion> versions = baseMapper.selectVersionsByFileId(fileId);
            
            // 批量软删除
            int affectedRows = baseMapper.deleteVersionsByFileId(fileId);

            // 减少存储对象引用计数
            for (FileVersion version : versions) {
                storageObjectService.decrementReferenceCount(version.getStorageObjectId(), 1);
            }

            log.info("删除文件所有版本成功: fileId={}, deletedCount={}", fileId, affectedRows);
            return affectedRows > 0;

        } catch (Exception e) {
            log.error("删除文件所有版本失败: fileId={}", fileId, e);
            return false;
        }
    }

    @Override
    public String compareVersions(String fileId, Integer fromVersion, Integer toVersion) {
        if (!StringUtils.hasText(fileId) || fromVersion == null || toVersion == null) {
            throw new IllegalArgumentException("文件ID和版本号不能为空");
        }

        try {
            FileVersion from = baseMapper.selectVersionByFileIdAndNumber(fileId, fromVersion);
            FileVersion to = baseMapper.selectVersionByFileIdAndNumber(fileId, toVersion);

            if (from == null || to == null) {
                return "版本不存在";
            }

            // 简单的对比信息（实际可以更复杂）
            StringBuilder diff = new StringBuilder();
            diff.append("版本对比: v").append(fromVersion).append(" -> v").append(toVersion).append("\n");
            diff.append("存储对象: ").append(from.getStorageObjectId()).append(" -> ").append(to.getStorageObjectId()).append("\n");
            diff.append("变更说明: ").append(to.getChangeLog()).append("\n");

            return diff.toString();

        } catch (Exception e) {
            log.error("版本对比失败: fileId={}, fromVersion={}, toVersion={}", fileId, fromVersion, toVersion, e);
            return "版本对比失败: " + e.getMessage();
        }
    }

    @Override
    public int countVersions(String fileId) {
        if (!StringUtils.hasText(fileId)) {
            return 0;
        }
        return baseMapper.countVersionsByFileId(fileId);
    }

    @Override
    public Map<String, Integer> batchCountVersions(List<String> fileIds) {
        if (fileIds == null || fileIds.isEmpty()) {
            return new HashMap<>();
        }

        Map<String, Integer> result = new HashMap<>();
        for (String fileId : fileIds) {
            result.put(fileId, countVersions(fileId));
        }
        return result;
    }

    @Override
    @Transactional
    public int cleanupHistoryVersions(String fileId, Integer keepCount) {
        if (!StringUtils.hasText(fileId) || keepCount == null || keepCount < 1) {
            throw new IllegalArgumentException("文件ID和保留数量不能为空且保留数量必须大于0");
        }

        try {
            List<FileVersion> versions = baseMapper.selectVersionsByFileId(fileId);
            if (versions.size() <= keepCount) {
                return 0; // 无需清理
            }

            // 保留最新的keepCount个版本，删除其余版本
            List<FileVersion> toDelete = versions.subList(keepCount, versions.size());
            int deletedCount = 0;

            for (FileVersion version : toDelete) {
                if (!version.getIsCurrent()) { // 不删除当前版本
                    if (deleteVersion(version.getId(), false)) {
                        deletedCount++;
                    }
                }
            }

            log.info("清理历史版本完成: fileId={}, keepCount={}, deletedCount={}", fileId, keepCount, deletedCount);
            return deletedCount;

        } catch (Exception e) {
            log.error("清理历史版本失败: fileId={}, keepCount={}", fileId, keepCount, e);
            return 0;
        }
    }

    @Override
    public String getVersionStatusText(Integer status) {
        if (status == null) {
            return "未知";
        }
        switch (status) {
            case 1: return "正常";
            case 0: return "禁用";
            case -1: return "已删除";
            default: return "未知状态";
        }
    }

    @Override
    public FileVersionVO convertToVO(FileVersion fileVersion) {
        if (fileVersion == null) {
            return null;
        }

        FileVersionVO vo = new FileVersionVO();
        vo.setId(fileVersion.getId());
        vo.setFileId(fileVersion.getFileId());
        vo.setStorageObjectId(fileVersion.getStorageObjectId());
        vo.setVersionNumber(fileVersion.getVersionNumber());
        vo.setVersionName(fileVersion.getVersionName());
        vo.setVersionDisplayName(fileVersion.getVersionDisplayName());
        vo.setIsCurrent(fileVersion.getIsCurrent());
        vo.setChangeLog(fileVersion.getChangeLog());
        vo.setVersionTags(fileVersion.getVersionTags());
        vo.setStatus(fileVersion.getStatus());
        vo.setStatusText(getVersionStatusText(fileVersion.getStatus()));
        vo.setCreatorId(fileVersion.getCreateBy());
        vo.setCreateVersionTime(fileVersion.getCreateTime());
        vo.setFirstVersion(fileVersion.getVersionNumber() != null && fileVersion.getVersionNumber() == 1);
        vo.setCreateTime(fileVersion.getCreateTime());
        vo.setUpdateTime(fileVersion.getUpdateTime());

        // TODO: 设置创建者名称、文件信息等扩展字段
        // vo.setCreatorName(getUserName(fileVersion.getCreateBy()));
        // vo.setFileName(getFileName(fileVersion.getFileId()));

        return vo;
    }

    @Override
    public List<FileVersionVO> convertToVOList(List<FileVersion> fileVersions) {
        if (fileVersions == null || fileVersions.isEmpty()) {
            return List.of();
        }
        return fileVersions.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }
}
